package com.newtouch.cq.security.controller;

import com.newtouch.cq.lang.em.BaseExceptionEnum;
import com.newtouch.cq.lang.result.MccObjectResult;
import com.newtouch.cq.lang.result.MccResult;
import com.newtouch.cq.lang.user.BaseUserDetails;
import com.newtouch.cq.security.token.TokenCache;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.WebAttributes;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.Serializable;

@SuppressWarnings("serial")
@Api(tags = "权限相关接口")
public class BaseAuthenticationController implements Serializable {

    protected String loginPageView = "/pages/login.html";

    @Autowired
    protected TokenCache<? extends UserDetails> tokenCache;

    @ApiIgnore
    @RequestMapping(value = "/loginPage", produces = {MediaType.TEXT_HTML_VALUE})
    public String loginPageHtml() {
        return loginPageView;
    }

    @ApiIgnore
    @RequestMapping(value = "/loginPage")
    @ResponseBody
    public MccResult loginPage() {
        return MccResult.PLEASE_LOGIN;
    }

    @ApiIgnore
    @ResponseBody
    @RequestMapping(value = "/loginSuccess")
    public MccObjectResult<Authentication> loginSuccess() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (null != authentication) {
            BaseUserDetails user = (BaseUserDetails) authentication.getPrincipal();
            String userKey = user.getUserKey();
            String tokenKey = user.getTokenKey();
            user.setPassword(null);
            tokenCache.saveToken(userKey, tokenKey, user);
        }
        return MccObjectResult.success(authentication);
    }

//    @RequestMapping(value = "/failure", produces = {MediaType.TEXT_HTML_VALUE})
//    public String failureHtml(HttpServletRequest request) {
//        return loginPageView;
//    }

    @ApiIgnore
    @ResponseBody
    @RequestMapping(value = "/failure")
    public ResponseEntity<MccResult> failure(HttpServletRequest request) {
        AuthenticationException exception = (AuthenticationException) request
                .getAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
        if (null == exception) {
            HttpSession session = request.getSession(false);
            if (session != null) {
                exception = (AuthenticationException) request.getSession()
                        .getAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
            }
        }
        MccResult result = MccResult.failureBmc(BaseExceptionEnum.ACCOUNT_PASSWORD_ERROR);
        if (null != exception) {
            result.setMessage(exception.getMessage());
        }
        return ResponseEntity.status(200).body(result);
    }


    /**
     * 退出登录
     * @return
     */
	@GetMapping("/loginOut")
	@ResponseBody
    @ApiOperation("退出登录")
//	@CacheEvict(value = SecurityConstants.TOKEN_USER_DETAIL, key = "#accesstoken")
	public MccResult loginOut() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (null != authentication) {
            BaseUserDetails user = (BaseUserDetails) authentication.getPrincipal();
            String userKey = user.getUserKey();
            String tokenKey = user.getTokenKey();
            user.setPassword(null);
            tokenCache.delToken(userKey, tokenKey);
        }
		SecurityContextHolder.clearContext();
		return MccResult.SUCCESS;
	}

//    @RequestMapping(value = "/logoutSuccess", produces = { MediaType.TEXT_HTML_VALUE })
//    @ResponseBody
//    @CacheEvict(value = SecurityConstants.TOKEN_USER_DETAIL, key = "#accesstoken")
//    public String logoutSuccessHtml(String accesstoken) {
//        SecurityContextHolder.clearContext();
//        return loginPageView;
//    }

    @RequestMapping(value = "/loginOutSuccess")
    @ResponseBody
    @ApiIgnore
//    @CacheEvict(value = SecurityConstants.TOKEN_USER_DETAIL, key = "#accesstoken")
    public MccResult loginOutSuccess() {
        SecurityContextHolder.clearContext();
        return MccResult.SUCCESS;
    }


    /**
     * 权限不足
     *
     * @return
     */
    @ApiIgnore
    @ResponseBody
    @RequestMapping(value = "/limit")
    public MccResult limit() {
        return MccResult.successMsg("权限不足");
    }

}
